package com.shwread.httpsdk.util;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;


/**
 * 简单的xml解析类：简单利用正则表达式的一种实现 少量xml数据情况下比sax简单高效
 * 
 * @author yangwc
 */
public class SimpleXmlHelper
{
	
	public static void setValue(String xmlData, String propName, String value) {
		xmlData.replaceAll("${" + propName + "}", value);
	}
	
	/**
	 * 获取属性值
	 * 
	 * <pre>
	 * getPropValue("<a b="222">111</a>","b")=222
	 * </pre>
	 * 
	 * @param xmlData
	 * @param propName
	 * @return
	 */
	public static String getPropValue(String xmlData, String propName) {
		String result = "";
//		xmlData = xmlData.replace("\n", ""); 
		StringBuilder sb = new StringBuilder();
		sb.append(" ");
		sb.append(propName);
		sb.append("=");
		sb.append("[\"\']");
		sb.append("(.*?)");//(.*?)
		sb.append("[\"\']");// 形如：message=["'](.*?)["']，即message="XXX"或message='XXX'
		Pattern pattern = Pattern.compile(sb.toString());
		Matcher matcher = pattern.matcher(xmlData);
		if (matcher.find())
		{
			result = matcher.group(1);
		}
		return result;
	}
	
	public static String getValue(String xmlData, String tagName, String tagValue, String propName) {
		String result = "";
		StringBuilder sb = new StringBuilder();
		sb.append("<");
		sb.append(tagName);
		sb.append(" ");
		sb.append(tagValue);
		sb.append("=");
		sb.append("\"");
		sb.append(propName);
		sb.append("\"");
		sb.append(">");
		sb.append("([\\s\\S]*)");// .*?
		sb.append("</");
		sb.append(tagName);
		sb.append(">");
		Pattern pattern = Pattern.compile(sb.toString());
		Matcher matcher = pattern.matcher(xmlData);
		if (matcher.find())
		{
			result = matcher.group(matcher.groupCount());// 总是返回最后一个group
		}
		return result.substring(0, 1);
	}
	
	/**
	 * 获取标签值
	 * 
	 * <pre>
	 * getTagValue(&quot;&lt;a&gt;111&lt;/a&gt;&quot;, &quot;a&quot;) = 111
	 * </pre>
	 * 
	 * @param xmlData
	 * @param tagName
	 * @return
	 */
	public static String getTagValue(String xmlData, String tagName) {
		String result = "";
		StringBuilder sb = new StringBuilder();
		sb.append("<");
		sb.append(tagName);
		sb.append("(.*?)");// .*?
		sb.append(">");
		sb.append("([\\s\\S]*)");// .*?
		sb.append("</");
		sb.append(tagName);
		sb.append(">");// 形如：<message(.*?)>([\\s\\S]*)</message>
		Pattern pattern = Pattern.compile(sb.toString());
		Matcher matcher = pattern.matcher(xmlData);
		if (matcher.find())
		{
			result = matcher.group(matcher.groupCount());// 总是返回最后一个group
		}
		return result;
	}
	
	public static List<String> getTagList(String xmlData, String tagName) {
		List<String> list = new ArrayList<String>();
		
		String endText = "</" + tagName + ">";
		String startText = "<" + tagName;
		String[] splitStrings = xmlData.split(endText);
		for (String splitString : splitStrings)
		{
			int index = splitString.indexOf(startText);
			if (index >= 0)
			{
				list.add(splitString.substring(index) + endText);
			}
		}
		
		return list;
	}
	
	/**
	 * 获取标签内容列表(用于分离多个标签相同的数据)
	 * 不含属性
	 * @param xmlData
	 * @param tagName
	 * @return
	 */
	public static ArrayList<String> getTagDataList(String xmlData, String tagName) {
		ArrayList<String> list = new ArrayList<String>();
		//    	StringBuilder sb = new StringBuilder();
		//    	sb.append("(<");
		//    	sb.append(tagName);
		//    	sb.append(".*>.*</");
		//    	sb.append(tagName);
		//    	sb.append(">)*");
		//    	StringBuilder sb = new StringBuilder("(<code.*?>.*?</code>)*");
		//    	Pattern pattern = Pattern.compile(sb.toString());
		//        Matcher matcher = pattern.matcher(xmlData);
		//        if (matcher.find()) {
		//            for(int i = 1; i <= matcher.groupCount(); i++) {
		//            	if(matcher.group(i) != null) {
		//            		list.add(matcher.group(i));
		//            	}
		//            }
		//        }
		
		String endText = "</" + tagName + ">";
		String startText = "<" + tagName + ">";
		String[] splitStrings = xmlData.split(endText);
		for (String splitString : splitStrings)
		{
			int index = splitString.indexOf(startText);
			if (index >= 0)
			{
				//list.add(splitString + endText);
				list.add(splitString.substring(index + startText.length()));
			}
		}
		return list;
	}
	
	public static void main(String[] args) {
		String xml = "<req cmd=\"login\" id=\"0001\" userid='0001' ver=\"\"><state1 user=\"057181930662\"/><a>112233</a></req>";
		
		String tagValue = getTagValue(xml, "req");
		//String propValue = getPropValue(xml, "userid");
		//System.out.println("tagValue:" + tagValue);
		//System.out.println("propValue:" + propValue);
	}
	
	public static String buildStrByTagAndValue(String tag, String value) {
		boolean bEmpty = false;
		bEmpty = value == null || value.trim().equals("");
		
		if (bEmpty)
		{
			StringBuilder sb = new StringBuilder(32);
			return sb.append("<").append(tag).append("/>").toString();
		}
		else
		{
			StringBuilder sb = new StringBuilder(128);
			return sb.append("<").append(tag).append(">").append(value).append("</").append(tag).append(">").toString();
		}
		
	}
	
	/**
	 * 传入sbBuild，减少申请，加快组包
	 */
	public static void insertStringBuilderByTagAndValue(StringBuilder sbBuild, String tag, String value) {
		boolean bEmpty = false;
		bEmpty = value == null || value.trim().equals("");
		
		if (bEmpty)
		{
			sbBuild.append("<").append(tag).append(" />").toString();
		}
		else
		{
			sbBuild.append("<").append(tag).append(">").append(value).append("</").append(tag).append(">").toString();
		}
	}
	
	/**
	 * 静默上传
	 */
	public static void insertStringBuilderByTagAndValueAndType(StringBuilder sbBuild, String tag, String value, String type) {
		boolean bEmpty = false;
		bEmpty = value == null || value.trim().equals("");
		
		if (bEmpty)
		{
			sbBuild.append("<").append(tag).append(" />").toString();
		}
		else
		{
			if (type == null || type.trim().equals(""))
			{
				sbBuild.append("<").append(tag).append(">").append(value).append("</").append(tag).append(">").toString();
			}
			else
			{
				sbBuild.append("<").append(tag).append(" type=\"").append(type).append("\">").append(value).append("</").append(tag).append(">").toString();
			}
		}
	}
	
	public static void parseXml(DefaultHandler mDefaultHandler, String input) {
		try
		{
			// 该方法总是会提示:DTD handlers aren't supported，以下方法可以避免
			// InputStream mInputStream = new
			// ByteArrayInputStream(input.getBytes());
			// SAXParserFactory.newInstance().newSAXParser().parse(mInputStream,mDefaultHandler);
			SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
			XMLReader xr = parser.getXMLReader();
			xr.setContentHandler(mDefaultHandler);
			xr.parse(new InputSource(new ByteArrayInputStream(input.getBytes())));
		}
		catch (SAXException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		catch (ParserConfigurationException e)
		{
			e.printStackTrace();
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public static String xmlEscape(String value) {
		value = replace(value, "&", "&amp;");
		value = replace(value, "<", "&lt;");
		value = replace(value, ">", "&gt;");
		value = replace(value, "\"", "&quot;");
		value = replace(value, "\'", "&apos;");
		return value;
	}
	
	public static String xmlUnEscape(String value) {
		value = replace(value, "&amp;", "&");
		value = replace(value, "&lt;", "<");
		value = replace(value, "&gt;", ">");
		value = replace(value, "&quot;", "\"");
		value = replace(value, "&apos;", "\'");
		return value;
	}
	
	public static String replace(String src, String olds, String news) {
		int index = src.indexOf(olds);
		if (index < 0) return src;
		StringBuffer sb = new StringBuffer(src.substring(0, index));
		int olen = olds.length();
		while (true)
		{
			sb.append(news);
			index += olen;
			int newIndex = src.indexOf(olds, index);
			if (newIndex < 0)
			{
				sb.append(src.substring(index));
				break;
			}
			sb.append(src.substring(index, newIndex));
			index = newIndex;
		}
		String result = sb.toString();
		return result;
	}
}
